#include "Scene.h"
#include "Common/CommonList.h"
#include "Common/Output.h"

#include "GL/glew.h"
#include "GL/glfw.h"


//#include "Maths/glm/glm.hpp"

#include "Objects/Plan.h"
#include "Objects/Triangle.h"
#include "Objects/Circle.h"
#include "Objects/Sphere.h"
#include "Objects/Cube.h"
#include "Engine.h"

//////////////////////////////////////////////////////////////////////////
Scene::Scene(void) : mCamera(new Camera)
{

}


//////////////////////////////////////////////////////////////////////////
Scene::~Scene(void)
{
	for (CommonList<GraphicComponent*>::iterator it = mObjects.begin();
		it != mObjects.end();
		++it)
	{
		delete *it;
	}

	delete mCamera;
}

//////////////////////////////////////////////////////////////////////////
void Scene::Init(GLuint aProgramId)
{
	mProgramID = aProgramId;
	mUniform1 = Engine::GetUniform(aProgramId, "mUniform1");
	mMVPUniform = Engine::GetUniform(aProgramId, "MVP");

	GraphicComponent* tPlan = new Plan();
	tPlan->GetTransform().Move(0,0,-3.f);

	GraphicComponent* tTri = new Triangle();
	tTri->GetTransform().Move(-1.f,-1.f,-2.f);

	GraphicComponent* tCu = new Cube();
	tCu->GetTransform().Move(1.f,1.f,-4.f);

	mObjects.AddFirst(tTri);
	mObjects.AddFirst(tCu);
	mObjects.AddFirst(tPlan);

	mCamera->Init();
	//mCamera->LookAt(tTri->GetTransform().GetPosition());
	mCamera->SetPosition(Vec3(2,1,6));

}

//////////////////////////////////////////////////////////////////////////
void Scene::Update(float aElapsedTime, bool aTransposeMatrix)
{
	Matrix tModelMatrix;
	if (aTransposeMatrix)
	{
		tModelMatrix = mCamera->GetViewMatrix().Transpose() * mProjectionMatrix->Transpose();
	}
	else
	{
		tModelMatrix =  *mProjectionMatrix * mCamera->GetViewMatrix();
	}
	CommonList<GraphicComponent*>::iterator it;
	for (it = mObjects.begin(); it != mObjects.end(); ++ it)
	{		
		// Send our transformation to the currently bound shader,
		// in the "MVP" uniform
		// For each model you render, since the MVP will be different (at least the M part)
		if (aTransposeMatrix)
			glUniformMatrix4fv(mMVPUniform, 1, GL_FALSE, ( (*it)->GetTransform().GetMatrixTransformForRender() * tModelMatrix).mLineMat);
		else
			glUniformMatrix4fv(mMVPUniform, 1, GL_FALSE, ( tModelMatrix * (*it)->GetTransform().GetConstMatrixTransform()).mLineMat);
		(**it).Draw();
	}
}